'use strict';

// +----------------------------------------------------------------------
// | CmsWing [ 网站内容管理框架 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2015-2115 http://www.cmswing.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: arterli <arterli@qq.com>
// +----------------------------------------------------------------------
/**
 * 插件前台控制器
 * 如果插件有前台展示业务，写在这个控制器里面
 * 插件如需建立表务必遵循下面格式：
 * 单表：表前缀_ext_插件目录名
 * 多表：表前缀_ext_插件目录名，表前缀_ext_插件目录名_分表1，表前缀_ext_插件目录名_分表2...
 */
module.exports = class extends think.cmswing.extIndex {
    /**
     * 支付列表
     */
    async paymentAction() {
        const { ctx } = this;
        const params = ctx.param();

        // 充值余额表单
        if (this.isAjax('POST') && params.type === 1) {
            const data = this.post();
            if (think.isEmpty(data.order_amount)) {
                return this.fail('请输入金额！');
            } else if (!think.isNumberString(data.order_amount)) {
                return this.fail('金额类型错误！');
            } else if (think.isEmpty(data.payment)) {
                return this.fail('必须选一种支付方式！');
            }

            // 用户
            data.user_id = this.user.uid;
            // 生成订单编号//todo
            // let nowtime = new Date().valueOf();
            // let oid = ["c", this.user.uid, nowtime]);
            data.order_no = await this.model('cmswing/order').orderid(this.user.uid);
            // 支付状态 pay_stayus 0:未付款 ,1:已付款
            data.pay_status = 0;
            // 订单状态 status 2:等待审核，3:已审核
            data.status = 2;
            // 发货状态 type 0:普通，1:充值
            data.type = 1;
            // 订单创建时间 create_time
            data.create_time = new Date().valueOf();

            // 生成订单
            const order_id = await this.model('order').add(data);

            // 支付日志
            const receiving = {
                order_id,
                user_id: this.user.uid,
                amount: data.order_amount,
                create_time: new Date().getTime(),
                payment_time: new Date().getTime(),
                doc_type: 1,
                payment_id: data.payment,
                pay_status: 0,
            };
            await this.model('doc_receiving').add(receiving);
            return this.success({
                name: '支付订单对接成功，正在转跳！', data: {
                    url: `/pay/${order_id}/${data.payment}`,
                },
            });
        }

        // 支付
        const userId = this.user.uid;
        const orderNo = params.ono; // 订单编号
        const orderId = params.order; // 订单ID
        const step = params.setp; // 订单步骤
        const orderType = parseInt(params.type); // 订单类型 0:购物 1: 充值

        // 读取支付配置
        const payList = await this.extModel('pay').where({
            status: 1,
        }).select();

        if (orderType === 0) {
            // 读取订单信息
            const where = {
                user_id: userId,
            };
            // 订单号或订单ID
            if (orderId !== 0) {
                where.id = orderId;
            } else {
                where.order_no = orderNo;
            }
            const orderInfo = await ctx.model('cmswing/order').where(where).find();

            if (!orderInfo.id) {
                return this.fail('我已经很努力了，还是没有找到你的订单');
            } else if (orderInfo.pay_status === 1) {
                return this.fail('你已经支付过了哦，去看看你的支付结果吧！');
            }

            // 格式化时间
            orderInfo.end_time = date_from(orderInfo.create_time + (Number(this.config('setup.ORDER_DELAY')) * 60000));

            this.assign('step', step);
            this.assign('order', orderInfo);
        }
        this.meta_title = '选取支付方式';
        this.assign('orderType', orderType);
        this.assign('payList', payList);
        return this.isMobile ? this.extDisplay('m') : this.extDisplay();
    }

    /**
     * 支付接口
     */
    async payAction() {
        const { ctx } = this;
        const params = ctx.param();

        const userId = this.user.uid;
        const orderId = params.order; // 订单ID
        const orderNo = params.ono; // 订单编号
        const payment = params.payment; // 支付方式

        // 读取订单信息
        const where = {
            user_id: userId,
        };
        // 订单号或订单ID
        if (orderId !== 0) {
            where.id = orderId;
        } else {
            where.order_no = orderNo;
        }

        // 查找订单信息
        const orderInfo = await ctx.model('cmswing/order').where(where).find();

        if (!orderInfo.id) {
            return this.fail('我已经很努力了，还是没有找到你的订单');
        } else if (orderInfo.pay_status === 1) {
            return this.fail('你已经支付过了哦，去看看你的支付结果吧！');
        }

        // 更新订单的支付方式
        await this.model('order').where({ id: orderId }).update({ payment });

        // 购物
        if (orderInfo.type === 0) {
            // 支付日志
            const receiving = {
                order_id: orderId,
                user_id: this.user.uid,
                amount: orderInfo.order_amount,
                create_time: new Date().getTime(),
                payment_time: new Date().getTime(),
                doc_type: 0,
                payment_id: payment,
                pay_status: 0,
            };

            // 100预付款支付
            if (params.payment === 100) {
                // 先检查下用户余额
                const balance = await this.model('member').where({ user_id: this.user.uid }).getField('amount', true);
                if (Number(balance) < Number(orderInfo.order_amount)) {
                    return this.fail('您余额不足，请充值，或者选择其他支付方式！');
                }
                // 扣款
                const decrement = this.model('member').where({ user_id: this.user.uid }).decrement('amount', Number(orderInfo.order_amount));
                if (decrement) {
                    // 扣款成功改变订单状态
                    await this.model('order').where({ order_no: orderInfo.order_no }).update({ status: 3, pay_status: 1 });

                    // 扣款成功后插入日志
                    const log = {
                        admin_id: 0,
                        user_id: this.user.uid,
                        type: 2,
                        time: new Date().valueOf(),
                        amount: (0 - Number(orderInfo.order_amount)),
                        amount_log: await this.model('member').where({ id: this.user.uid }).getField('amount', true),
                        note: `${await get_nickname(this.user.uid)} 通过余额支付方式进行商品购买,订单编号：${orderInfo.order_no}`,
                    };

                    await this.model('balance_log').add(log);
                    receiving.pay_status = 1;
                    await this.model('doc_receiving').add(receiving);
                    const url = `/pay/deduction/result?out_trade_no=${orderInfo.order_no}`;
                    return ctx.redirect(url); // 重定向到支付结果
                }
            }

            // 货到付款
            // if (params.payment === 1001) {}
        }

        // 支付接口
        const payService = this.extService('alipay'); // 支付服务

        this.body = await payService.pay({
            orderNo: orderInfo.order_no, // 商户订单号,64个字符以内、可包含字母、数字、下划线；需保证在商户端不重复
            price: orderInfo.order_amount, // 订单总金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000]
            title: orderInfo.type === 1 ? '余额充值' : '购买商品', // 订单标题
        }, ctx.isMobile); // 发送支付请求
    }

    /**
     * 支付同步结果
     */
    async resultAction() {
        const { ctx } = this;
        const params = ctx.param();
        const payType = params.payType; // 支付类型
        const orderNo = params.out_trade_no; // 订单号
        delete params.payType; // 删除支付类型属性
        // 查找订单信息
        const orderInfo = await this.model('order').where({
            order_no: orderNo,
        }).find();
        // 订单状态为未支付
        if (orderInfo.pay_status === 0) {
            if (payType === 'alipay') {
                // 支付宝支付
                const verify = await this.extService('alipay').verify(params);
                // 判断签名
                if (!verify) {
                    think.logger.info('支付宝支付通知验签失败', params);
                    this.body = 'fail';
                    return;
                }
                // 请求支付结果
                const queryResult = await this.extService('alipay').query(orderNo);
                // 判断支付结果
                if (queryResult.tradeStatus === 'TRADE_SUCCESS' || queryResult.tradeStatus === 'TRADE_FINISHED') {
                    // 修改订单状态
                    await this.model('order').payComplete(orderNo, queryResult, payType);
                    orderInfo.pay_status = 1;
                }
                orderInfo.payType = '支付宝';
            } else if (payType === 'wechat') {
                // 微信支付
            }
        }
        this.meta_title = '支付结果';
        this.assign('order', orderInfo);
        return this.extDisplay();
    }

    /**
     * 支付异步结果
     */
    async notifyAction() {
        const { ctx } = this;
        const payType = ctx.get('type');
        const postData = ctx.post();

        // 验签
        if (payType === 'alipay') {
            /** 支付宝支付 */
            const verify = await this.extService('alipay').verify(postData);

            if (!verify) {
                think.logger.info('支付宝支付通知验签失败', postData);
                this.body = 'fail';
                return;
            }

            if (postData.trade_status === 'TRADE_SUCCESS' || postData.trade_status === 'TRADE_FINISHED') {
                /** 支付成功 查找订单信息 并处理 */
                const orderNo = postData.out_trade_no; // 订单号

                // 修改订单状态
                await this.model('order').payComplete(orderNo, postData, payType);

            } else {
                think.logger.info('支付宝支付通知其它状态');
            }

            this.body = 'success';
        }
    }
};
